<template>
  <div class="app-container">
    <el-row :gutter="20">
      <!-- 左侧AI交互区域 -->
      <el-col :span="12">
        <el-card class="box-card">
          <template #header>
            <div class="card-header">
              <span>AI大纲助手</span>
            </div>
          </template>
          <NovelAiChat
            ref="aiChatRef"
            title="AI大纲助手"
            placeholder="请描述您想要生成的章节大纲，例如：'请为第一章生成详细的大纲，包括主要情节、人物对话和场景描写'"
            :loading="isSummaryLoading"
            :enable-context="enableContext"
            @send="handleAiChat"
            @context-change="handleContextChange"
            @abort="handleAbortAI"
          />
        </el-card>
      </el-col>

      <!-- 右侧大纲列表 -->
      <el-col :span="12">
        <el-card class="box-card">
          <template #header>
            <div class="card-header">
              <span>AI生成的章节大纲</span>
              <div class="right">
                <el-button type="primary" @click="handleBatchSave" :disabled="!outlines.length">保存到数据库</el-button>
                <el-button type="danger" @click="handleBatchDelete" :disabled="!selectedOutlines.length">删除选中</el-button>
              </div>
            </div>
          </template>
          
          <el-table
            v-loading="loading"
            :data="outlines"
            @selection-change="handleSelectionChange"
            border
          >
            <el-table-column type="selection" width="55" align="center" />
            <el-table-column label="序号" type="index" width="50" align="center" />
            <el-table-column label="大纲标题" prop="title" min-width="120">
              <template #default="{ row }">
                <el-input v-model="row.title" placeholder="大纲标题" />
              </template>
            </el-table-column>
            <el-table-column label="大纲内容" prop="summary" min-width="200">
              <template #default="{ row }">
                <el-input
                  v-model="row.summary"
                  type="textarea"
                  :rows="4"
                  placeholder="大纲内容"
                />
              </template>
            </el-table-column>
            <el-table-column label="操作" align="center" width="120">
              <template #default="{ row, $index }">
                <el-button
                  type="danger"
                  link
                  @click="handleDelete($index)"
                >删除</el-button>
              </template>
            </el-table-column>
          </el-table>

          <div class="outline-tips" v-if="!outlines.length">
            <el-empty description="请在左侧与AI对话，生成章节大纲" />
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue'
import { useRoute } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import NovelAiChat from '@/components/NovelAiChat/index.vue'
import { listChapterOutline, addChapterOutline, updateChapterOutline, delChapterOutline } from '@/api/novel/chapterOutline'
import { useAIStream, PlatformType, AIModelType } from '@/components/Hook/useStreamFetch'

const route = useRoute()
const chapterId = ref(route.params.chapterId)
const loading = ref(false)
const outlines = ref([])
const selectedOutlines = ref([])
const aiChatRef = ref(null)
const enableContext = ref(true)
const aiLoading = ref(false)

// 创建 AI 对话实例
const summaryHook = useAIStream({
  platform: PlatformType.VOLCANO,
  authToken: 'f9c1148b-26fc-4c92-8977-fca871de1af3',
  model: AIModelType.DEEPSEEK,
  enableContext: true,
  maxContextMessages: 10
})

// 解构出来用于控制和显示
const {
  data: summaryData,
  isLoading: isSummaryLoading,
  error: summaryError,
  chat: startAiChat,
  abortFetch: abortSummary,
  lastMessage
} = summaryHook

// 记录上一次解析的文本长度
let lastParsedLength = 0;

// 监听AI响应数据，进行实时解析和显示
watch(summaryData, (newVal) => {
  if (newVal) {
    // 更新AI对话内容 - 流式显示
    aiChatRef.value?.addAiResponse({ isStreaming: true, content: newVal })
    
    // 实时解析大纲信息
    if (newVal.length > lastParsedLength) {
      parseOutlineData(newVal);
      lastParsedLength = newVal.length;
    }
  }
})

// 监听AI加载状态
watch(isSummaryLoading, (isLoading) => {
  aiLoading.value = isLoading
  if (!isLoading && lastMessage.value) {
    // 流程结束时进行最后的完整解析
    parseOutlineData(lastMessage.value, true);
    // 结束流式显示
    aiChatRef.value?.addAiResponse({ isStreaming: true, end: true })
    // 重置解析长度
    lastParsedLength = 0;
  }
})

// 处理终止AI对话
const handleAbortAI = () => {
  abortSummary()
  aiLoading.value = false
  // 结束流式显示
  aiChatRef.value?.addAiResponse({ isStreaming: true, end: true })
}

// 解析大纲数据的函数
const parseOutlineData = (content, isFinal = false) => {
  let currentOutline = { title: '', summary: '' }
  let isCollectingOutline = false
  let tempOutlines = [] // 临时存储完整的大纲信息
  
  try {
    const lines = content.split('\n')
    
    for (const line of lines) {
      // 检查是否开始新的大纲
      if (line.includes('大纲标题：')) {
        // 如果已经在收集大纲信息，先保存当前大纲
        if (isCollectingOutline && currentOutline.title && currentOutline.summary) {
          tempOutlines.push({
            ...currentOutline,
            orderIndex: tempOutlines.length + 1
          })
        }
        
        // 开始收集新的大纲信息
        isCollectingOutline = true
        currentOutline = {
          title: line.split('：')[1]?.trim() || '',
          summary: ''
        }
      }
      // 检查是否是大纲内容
      else if (line.includes('大纲内容：') && isCollectingOutline) {
        currentOutline.summary = line.split('：')[1]?.trim() || '';
      }
      // 如果遇到空行且正在收集大纲信息，保存当前大纲
      else if (line.trim() === '' && isCollectingOutline && currentOutline.title && currentOutline.summary) {
        tempOutlines.push({
          ...currentOutline,
          orderIndex: tempOutlines.length + 1
        })
        isCollectingOutline = false
        currentOutline = { title: '', summary: '' }
      }
      // 如果正在收集内容，追加内容
      else if (isCollectingOutline && currentOutline.title && line.trim() !== '') {
        if (currentOutline.summary) {
          currentOutline.summary += '\n' + line.trim();
        } else {
          currentOutline.summary = line.trim();
        }
      }
    }
    
    // 处理最后一个大纲
    if (isCollectingOutline && currentOutline.title && currentOutline.summary) {
      tempOutlines.push({
        ...currentOutline,
        orderIndex: tempOutlines.length + 1
      })
    }
    
    // 只有在最终解析或者有完整大纲时才更新
    if (tempOutlines.length > 0 && (isFinal || tempOutlines.every(v => v.title && v.summary))) {
      outlines.value = tempOutlines;
      if (isFinal) {
        ElMessage.success(`成功生成 ${tempOutlines.length} 个大纲`);
      }
    }
  } catch (error) {
    console.error('解析AI响应失败:', error);
  }
}

// 处理AI对话
const handleAiChat = async (data) => {
  try {
    const { message, context } = data
    
    // 系统提示词
    const systemPrompt = `你是一个专业的小说章节大纲设计助手。请根据用户的需求，生成详细的章节大纲。
要求：
1. 每个大纲必须包含标题和详细内容
2. 大纲标题要简洁有力，能体现该部分的核心内容
3. 大纲内容要详细描述该部分的情节发展，包括：
   - 主要情节发展
   - 重要人物对话
   - 场景描写
   - 情感变化
   - 伏笔设置
4. 大纲之间要有连贯性，体现故事的发展脉络
5. 请严格按照以下格式输出每个大纲：
---
大纲标题：xxx
大纲内容：xxx
---

注意：
- 每个大纲之间用空行分隔
- 大纲标题和内容要清晰明确
- 确保每个大纲的信息完整
- 请一次完整输出所有大纲信息`

    // 开始流式显示
    aiChatRef.value?.addAiResponse({ isStreaming: true, start: true })
    
    // 重置解析长度
    lastParsedLength = 0;
    
    // 使用优化后的AI聊天函数
    await startAiChat(message, systemPrompt)
    
  } catch (error) {
    console.error('AI生成失败:', error)
    ElMessage.error('AI生成失败，请重试')
    // 结束流式显示
    aiChatRef.value?.addAiResponse({ isStreaming: true, end: true })
  } finally {
    aiLoading.value = false
  }
}

// 处理上下文变化
const handleContextChange = (value) => {
  if (!value) {
    ElMessageBox.confirm(
      '禁用上下文后，AI将无法看到之前的对话历史。确定要禁用吗？',
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    ).then(() => {
      aiChatRef.value?.clearHistory()
      enableContext.value = false
      ElMessage.success('已禁用上下文，对话历史已清空')
    }).catch(() => {
      enableContext.value = true
    })
  } else {
    enableContext.value = true
    ElMessage.success('已启用上下文，AI可以看到之前的对话历史')
  }
}

// 处理表格选择变化
const handleSelectionChange = (selection) => {
  selectedOutlines.value = selection
}

// 处理删除单个大纲
const handleDelete = (index) => {
  outlines.value.splice(index, 1)
  // 更新序号
  outlines.value.forEach((outline, idx) => {
    outline.orderIndex = idx + 1
  })
}

// 处理批量删除
const handleBatchDelete = () => {
  ElMessageBox.confirm(
    '确定要删除选中的大纲吗？',
    '提示',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(() => {
    const selectedIndexes = selectedOutlines.value.map(outline => 
      outlines.value.findIndex(o => o === outline)
    ).sort((a, b) => b - a)
    
    selectedIndexes.forEach(index => {
      outlines.value.splice(index, 1)
    })
    
    // 更新序号
    outlines.value.forEach((outline, idx) => {
      outline.orderIndex = idx + 1
    })
    
    ElMessage.success('删除成功')
  })
}

// 处理批量保存
const handleBatchSave = async () => {
  try {
    loading.value = true
    const promises = outlines.value.map(outline => {
      const data = {
        chapterId: chapterId.value,
        title: outline.title,
        summary: outline.summary,
        orderIndex: outline.orderIndex,
        parentId: 0 // 默认为顶级大纲
      }
      
      if (outline.id) {
        return updateChapterOutline({ ...data, id: outline.id })
      } else {
        return addChapterOutline(data)
      }
    })
    
    await Promise.all(promises)
    ElMessage.success('保存成功')
    getList()
  } catch (error) {
    console.error('保存失败:', error)
    ElMessage.error('保存失败，请重试')
  } finally {
    loading.value = false
  }
}

// 获取大纲列表
const getList = async () => {
  try {
    loading.value = true
    const response = await listChapterOutline({ chapterId: chapterId.value })
    outlines.value = response.rows.map(item => ({
      id: item.id,
      title: item.title,
      summary: item.summary,
      orderIndex: item.orderIndex
    }))
  } catch (error) {
    console.error('获取大纲列表失败:', error)
    ElMessage.error('获取大纲列表失败')
  } finally {
    loading.value = false
  }
}

onMounted(() => {
  getList()
})
</script>

<style scoped>
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.right {
  display: flex;
  gap: 10px;
}

.outline-tips {
  margin-top: 20px;
  text-align: center;
  color: #909399;
}

:deep(.el-card__header) {
  padding: 10px 20px;
}

:deep(.el-card__body) {
  padding: 20px;
}

:deep(.el-table) {
  margin-top: 10px;
}

:deep(.el-input__wrapper) {
  box-shadow: none !important;
}

:deep(.el-textarea__inner) {
  box-shadow: none !important;
}
</style> 